import java.util.*;

class Program {
  public static int[] mergeSort(int[] array) {
    if(array == null || array.length == 0) return array;

    mergeSortUtil(array, 0, array.length - 1);
    return array;
  }

  private static void mergeSortUtil(int[] array, int left, int right) {
    if(left >= right) return;

    int middle = left + (right - left) / 2;

    mergeSortUtil(array, left, middle); // T(n/2)
    mergeSortUtil(array, middle + 1, right);

    merge(array, left, middle, middle + 1, right); // O(n)
  }

  private static void merge(int[] array, int left, int leftEnd, int right, int rightEnd) {
    int sortedArraySize = rightEnd - left + 1;
    int[] sortedArray = new int[sortedArraySize];

    int leftPtr = left, rightPtr = right, sortedPtr = 0;
    while(leftPtr <= leftEnd && rightPtr <= rightEnd) {
      if(array[leftPtr] < array[rightPtr]) {
        sortedArray[sortedPtr++] = array[leftPtr++];
      } else {
        sortedArray[sortedPtr++] = array[rightPtr++];
      }
    }

    while(leftPtr <= leftEnd) {
      sortedArray[sortedPtr++] = array[leftPtr++];
    }
    
    while(rightPtr <= rightEnd) {
      sortedArray[sortedPtr++] = array[rightPtr++];
    }

    System.arraycopy(sortedArray, 0, array, left, sortedArraySize);
  }



}
